var URL = window.URL || window.webkitURL || window.mozURL;

onAppReady(function(params) {
	CSSPlugin.install();
	var loadedImages = params.loadedImages;
	Ticker.setFPS(20);
	
	var msg = modernizr([
		'canvas', 'audio', 'video',
		'borderradius', 'backgroundsize', 'opacity',
		'cssgradients', 'csstransforms', 'csstransitions'
	]);
	if(msg.length > 0){ alert(msg.join('\n')); }
	
	// i18n description of this example.
	$('#about').html(msg_aboutThisExample);
	
	function adjustWhalePosition() {
		var whaleWrapper = $('#whaleWrapper');
		whaleWrapper.css('left', ($(document).width() - whaleWrapper.width()) / 2).show();
	}
	adjustWhalePosition();
	
	$(window).resize(function(){
		adjustWhalePosition();
	});
	
	$(document.body).on('dragenter dragover drop', function(e) {
		e.preventDefault();
	});
	
	var whale = $("#whale");
	var playing = false;
	var pauseFunc;
	var pukapukaTween = Tween.get(whale[0], {loop: true, css: true})
		.to({ bottom: 15 }, 1500, Ease.easeIn)
		.to({ bottom: 0 }, 2500, Ease.easeIn);

	//moving the clouds
	Tween.get($('#cloud_slow')[0], {loop: true, css: true})
		.to({
			right: -1001 // backgorund-image's width
		}, 105000, Ease.easeIn);

	Tween.get($('#cloud_fast')[0], {loop: true, css: true})
		.to({
			right: -1001 // backgorund-image's width
		}, 80000, Ease.easeIn);
	
	//moving the birds
	Tween.get($('#birds')[0], {loop: true, css: true})
		.call(function(){
			$(this).attr('class', 'second');
		}).wait(800)
		.call(function(){
			$(this).attr('class', 'third');
		}).wait(800)
		.call(function(){
			$(this).attr('class', 'fourth').fadeOut(2000);
		}).wait(10000).call(function(){
			$(this).attr('class', '').fadeIn(1000);
		}).wait(800);
		
	//moving the right fins
	Tween.get($('#finRight')[0], {loop: true, css: true})
		.call(function(){
			$(this).toggleClass('up');
		}).wait(1500);

	//moving the left fins
	Tween.get($('#finLeft')[0], {loop: true, css: true})
		.call(function(){
			$(this).toggleClass('up');
		}).wait(1500);

	//moving the tail fins
	Tween.get($('#finTail')[0], {loop: true, css: true})
		.call(function(){
			$(this).toggleClass('up');
		}).wait(1500);

	//moving the front wave
	Tween.get($('#waveFront')[0], {loop: true, css: true})
		.to({left: -10, bottom: -15}, 1500, Ease.easeIn)
		.to({left: 0, bottom: 0}, 1500, Ease.easeIn);

	//moving the second wave
	Tween.get($('#waveBack')[0], {loop: true, css: true})
		.to({left: -15, bottom: -10}, 1200, Ease.easeIn)
		.to({left: 0, bottom: 0}, 1200, Ease.easeIn);
	
	// mogumogu & hammer
	var mogumogu = $('#mogumogu');
	var hammer = $('#hammer');
	
	$('#whaleBody').click(function(e) {
		if(playing !== true){ return; }

		typeof pauseFunc === 'function' && pauseFunc();
		pauseFunc = null;
		
		var whaleBody = $('#whaleBody').css('background', 'url(./images/whale_stop.png) no-repeat').show();
		mogumogu.hide();
		hammer.show();
		Tween.get(hammer[0], {loop:false, css:true})
			.wait(1000)
			.call(function(){
					$(this).hide();
			});
		
		$('#note').hide();
		mogNormal(2000);
	});
	
	$("#mouthOfWhale")
	.on("dragenter", function(e) {
		e.preventDefault();
	})
	.on("dragover", function(e) {
		e.preventDefault();
	})
	.on("drop", function(e) {
		e.stopPropagation();
		
		$('#whaleBody').css('background', 'url(./images/whale.png) no-repeat');
		
		var mogumoguTween =	Tween.get(mogumogu[0], {loop: false, css: true});
		for (var i = 0; i < 6; i++) {
			(function(idx) {
				var css = idx % 2 === 0 ? 'url(./images/eat_mouse1.png) no-repeat' : 'url(./images/eat_mouse2.png) no-repeat';
				mogumoguTween.call(function() {
					mogumogu.css('background', css).show();
				}).wait(350)
			})(i);
		}
		
		var files = e.originalEvent.dataTransfer.files;
		var file = files[0] || null;
		
		mogumoguTween.call(function() {
			var fileType = (file && file.type)? file.type: '';
			if (fileType.indexOf('text/') === 0) {
				processTextFile(file);
			} else if (fileType.indexOf('image/') === 0) {
				processImageFile(file);
			} else if (fileType.indexOf('video/') === 0 &&
				/probably|maybe/.test($('#tv')[0].canPlayType(fileType))) {
					processVideoFile(file);
			} else if (fileType.indexOf('audio/') === 0 &&
				/probably|maybe/.test($('#audioPlayer')[0].canPlayType(fileType))) {
					processAudioFile(file);
			} else {
				processOtherFile(file);
			}
		});
	});
	function processVideoFile(file) {
		var whale = $('#whale');
		var island = $('#island');
		var tv = $('#tv');
		var whaleMovie = $('#whaleMovie');
		var videoData = URL.createObjectURL(file);
		
		Tween.get(whale[0], {loop: false, css: true, override: true})
			.wait(500)
			.to({bottom: -370}, 2000, Ease.easeIn)
			.call(function() {
				Tween.get(island[0], {loop:false, css:true})
				.to({width: 300, height: 376}, 0)
				.to({width: 478, height: 600}, 2000, Ease.easeIn)
				.call(function() {
					Tween.get(tv[0], {loop:false, css:true})
					.to({top: 150, left: 100, width: 80}, 0)
					.to({top: 217, left: 157, width: 140}, 2000, Ease.easeIn);
				
					Tween.get(whaleMovie[0], {loop:false, css:true, override: true})
						.to({bottom: -600}, 0)
						.to({bottom: -200}, 2000, Ease.easeIn)
						.wait(1500)
						.call(function() {
							tv.attr('src', videoData).show();
							
							var stopTxt = $('#stopTxt').show();
							var stopTxtTween = Tween.get(stopTxt[0], {loop: true, css: true})
								.call(function(){
									$(this).toggleClass('up');
								}).wait(2000);

							
							pauseFunc = function() {
								tv[0].pause();
								playing = false;
							};
							
							$('#moviePlay').on('click', function(){
								tv[0].play();
								playing = true;
							});
							
							$('#movieStop').on('click', function(){
								pauseFunc();	
							});
							
							tv.on('ended', function(){
								pauseFunc();
								afterEffect();
							});
					});
				});
		});
		
		function afterEffect(){
			$('#moviePlay, #movieStop').off('click');
			tv.off('ended').hide();
			tv[0].src = videoData = null;
			
			Tween.get(whaleMovie[0], {loop:false, css:true})
				.wait(2000)
				.to({bottom: -200}, 0)
				.to({bottom: -600}, 2000).wait(1000)
				.call(function(){
					Tween.get(island[0], {loop:false, css:true})
						.to({width: 300, height: 376}, 2000, Ease.easeIn);
					Tween.get(whale[0], {loop: false, css: true})
						.to({bottom: 0}, 2000, Ease.easeIn)
						.call(function(){
							mogNormal(2000);
							$('#whaleSideways').off('click');
						});
			});
		}
		
		$('#whaleSideways').click(function(e) {
			tv[0].pause();
			$('#hammerMovie').show();
			$('#whaleSideways').css('backgroundImage', 'url(./images/whale_movie_stop.png)').show();
			$('#stopTxt').hide();
			
			var hammerMovieTween = Tween.get(hammerMovie[0], {loop: false, css: true});
			var stopImg = $('#stopImg').show();
			var stopImgTween = Tween.get(stopImg[0], {loop: false, css: true});

			for (var i = 0; i < 8; i++) {
				(function(idx) {
					var css = idx % 2 === 0 ? 'url(./images/stop_img1.png) no-repeat' : 'url(./images/stop_img2.png) no-repeat';
					stopImgTween.call(function() {
						stopImg.css('background', css).show();
					}).wait(300)
				})(i);
			}
			
			stopImgTween.call(function(){
				$(this).hide();
			}).wait(3000)
			.call(function(){
				　$('#whaleSideways').css('backgroundImage', 'url(./images/whale_sideways.png)').show();
			}).wait(1000);
					
			Tween.get($('#hammerMovie')[0], {loop:false, css:true})
				.wait(1000)
				.call(function(){
					$(this).hide();
					
					Tween.get($('#stopTxt')[0], {loop:false, css:true})
						.call(function(){
							$(this).hide();
							afterEffect();
						}).wait(1000);
			});
		});
	}
	function processAudioFile(file) {
		$("#finLeft").hide();
		var finMusic = $('#finMusic').css('background', 'url(./images/fin_music.png) no-repeat').show();
		
		var audio = $('#audioPlayer')[0];
		var audioData = URL.createObjectURL(file);
		audio.src = audioData;
		audio.play();
		
		var note = $('#note').show();
		var noteTween = Tween.get(note[0], {loop: true, css: true})
			.call(function(){
				$(this).toggleClass('up');
			}).wait(1500);

		playing = true;
		pauseFunc = function() {
			audio.pause();
			audio.src = audioData = null;
			playing = false;
		};
		
		$(audio).bind('ended', function(){
			pauseFunc();
			mogNormal(1000);
		});
	}
	function processOtherFile(file) {
		mogumogu.hide();
		$('#whaleBody').css('backgroundImage', 'url(./images/whale_error.png)').show();
		$('#error').css('backgroundImage', 'url(./images/error.png)').show().fadeOut(3000);
		$('#error_txt').css('backgroundImage', 'url(./images/error_txt.png)').show().fadeOut(3000);
		mogNormal(3000);
	}
	function processTextFile(file) {
		var reader = new FileReader();
		reader.onload = function() {
			var text = reader.result;
			var lines = text.split(/\n/);
			var balloon = $("#wordsBalloon").empty().show();
			var lineCount = 0;
			
			var timer = -1;
			pauseFunc = function() {
				clearTimeout(timer);
				balloon.hide();
				mogNormal(1000);
				playing = false;
			};
			var speak = function() {
				balloon.text(lines[lineCount]);
				lineCount++;
				if (lineCount === lines.length) {
					pauseFunc();
					return;
				}
				timer = setTimeout(speak, 1000);
			};
			
			timer = setTimeout(speak, 1000);
			playing = true;
		};
		reader.readAsText(file, 'UTF-8');
	}
	function processImageFile(file) {
		var reader = new FileReader();
		reader.onload = function() {
			var tmpImg = document.createElement('img');
			tmpImg.src = reader.result;
			tmpImg.onload = function() {
				var drawCanvas = $('#pict');
				var canvasWidth = drawCanvas.attr('width'), canvasHeight = drawCanvas.attr('height');
				var canvasProp = calcCanvasPosition(tmpImg.naturalWidth, tmpImg.naturalHeight, canvasWidth, canvasHeight);
				var pictCtx = drawCanvas[0].getContext('2d');
				pictCtx.clearRect(0, 0, canvasWidth, canvasHeight);
				
				var ctx = document.createElement('canvas').getContext('2d');
				ctx.drawImage(tmpImg, 0, 0, tmpImg.naturalWidth, tmpImg.naturalHeight, canvasProp.dx, canvasProp.dy, canvasProp.width, canvasProp.height);
				
				var imageData = ctx.getImageData(canvasProp.dx, canvasProp.dy, canvasProp.width, canvasProp.height);
				var usedColorList = $('#usedColors').empty();
				var colors = findUsedColors(imageData);
				colors.forEach(function(color) {
					var rgb = rgbToString(color.color);
					var count = color.count;
					usedColorList.append($('<li>', {
						css: { 'backgroundColor': rgb }
					}));
				});
				
				$("#colorsBalloon").show();
				
				var RAINBOW_STROKE = 40;
				$('.rainbow canvas').each(function(idx){
					var ctx = $(this).get(0).getContext('2d');
					ctx.beginPath();
					ctx.arc($(this).width()/2, $(this).height()/2, $(this).width()/2 - (idx+1) * RAINBOW_STROKE, Math.PI * 0.1, Math.PI, false);
					ctx.lineWidth = RAINBOW_STROKE + 1;
					ctx.strokeStyle = rgbToString(colors[idx].color);
					ctx.stroke();
				});
				
				var RAINBOW_INTERVAL =600;
				var colorIdx = 0;
				var interval = setInterval(function(){
					var rainbow = $($('.rainbow canvas')[colorIdx]);
					paintNearColortOnly(ctx, pictCtx, canvasProp, colors[colorIdx].color);
					rainbow.css({
						'transform': 'rotate(-180deg)',
						'-o-transform': 'rotate(-180deg)',
						'-moz-transform': 'rotate(-180deg)',
						'-webkit-transform': 'rotate(-180deg)',
						'-ms-transform': 'rotate(-180deg)',
						'transition': 'transform 500ms ease-in',
						'-o-transition': '-o-transform 500ms ease-in',
						'-moz-transition': '-moz-transform 500ms ease-in',
						'-webkit-transition': '-webkit-transform 500ms ease-in',
						'-ms-transition': '-ms-transform 500ms ease-in'
					}).one('webkitTransitionEnd', function(e){
						// something to do
						e.preventDefault();
					});
					
					colorIdx ++;
					
					if(colorIdx >= colors.length){
						var timer = setTimeout(function(){
							pictCtx.drawImage(tmpImg, canvasProp.dx, canvasProp.dy, canvasProp.width, canvasProp.height);
							mogNormal(3000);
							clearTimeout(timer);
							timer = null;
						}, RAINBOW_INTERVAL);
						
						clearInterval(interval);
						interval = null;
						reader = null;
					}
				}, RAINBOW_INTERVAL);
			};
		};
		reader.readAsDataURL(file);
	}
	function findUsedColors(imageData) {
		var TOP = 5, OPACITY_THRESHOLD = .1;
		var usedColors = []; // [{color: {rgb}, count: n}]
		var imageDataArray = imageData.data;
		for (var i = 0, n = imageDataArray.length; i < n; i+=4) {
			var r = imageDataArray[i];
			var g = imageDataArray[i+1];
			var b = imageDataArray[i+2];
			var a = imageDataArray[i+3];
			
			if (a < OPACITY_THRESHOLD) {
				continue;
			}
			var color = { r: r, g: g, b: b };
			var nearColor = findNearColor(color, usedColors);
			if (nearColor >= 0) {
				usedColors[nearColor].count++;
			} else {
				usedColors.push({
					color: color,
					count: 1
				});
			}
		}
		usedColors.sort(function(a, b) {
			return b.count - a.count;
		});
		return usedColors.slice(0, TOP);
	}
	function rgbToString(color) {
		return '#' + byteToHex(color.r) + byteToHex(color.g) + byteToHex(color.b); 
	}
	function byteToHex(n) {
		var hex = n.toString(16);
		if (hex.length === 1) {
			hex = '0' + hex;
		}
		return hex;
	}
	function findNearColor(color, colors) {
		for (var i = 0, n = colors.length; i < n; i++) {
			var color2 = colors[i].color;
			if (isNearColor(color, color2)) {
				return i;
			}
		}
		return -1;
	}
	function isNearColor(color1, color2) {
		var THRESHOLD = 70;
		var rDiff = color1.r - color2.r;
		var gDiff = color1.g - color2.g;
		var bDiff = color1.b - color2.b;
		return (rDiff * rDiff + gDiff * gDiff + bDiff * bDiff) < THRESHOLD;
	}
	function mogNormal(wait) {
		setTimeout(function() {
			// image file
			$('#colorsBalloon').fadeOut();
			$('.rainbow canvas').fadeOut(1, function(){
				$(this).css({
					'transform': 'rotate(0deg)',
					'-o-transform': 'rotate(0deg)',
					'-moz-transform': 'rotate(0deg)',
					'-webkit-transform': 'rotate(0deg)',
					'-ms-transform': 'rotate(0deg)'
				}).show();
			});
			// audio file
			$('#finMusic').hide();
			$('#note').fadeOut(600);
			
			// dafault state
			mogumogu.hide();
			$("#mouthOfWhale, #finLeft, #finRight").show();
			$('#whaleBody').css('backgroundImage', 'url(./images/whale_drop.png)');
		}, wait || 0);
	}
	function paintNearColortOnly(orgCtx, dstCtx, canvasProp, color){
		var OPACITY_THRESHOLD = .1;
		var isNear = false;
		
		var workImageData = orgCtx.getImageData(canvasProp.dx, canvasProp.dy, canvasProp.width, canvasProp.height);
		var workImageDataArray = workImageData.data;
		
		for (var i = 0, n = workImageDataArray.length; i < n; i+=4) {
			var currentColor = {
				r : workImageDataArray[i],
				g : workImageDataArray[i+1],
				b : workImageDataArray[i+2],
				a : workImageDataArray[i+3]
			};
			
			isNear = (currentColor.a < OPACITY_THRESHOLD)? false: isNearColor(color, currentColor);
			
			if(isNear){
				workImageData.data[i] = currentColor.r;
				workImageData.data[i+1] = currentColor.g
				workImageData.data[i+2] = currentColor.b
				workImageData.data[i+3] = currentColor.a
			} else {	// paint white
				workImageData.data[i] = 255;
				workImageData.data[i+1] = 255;
				workImageData.data[i+2] = 255;
				workImageData.data[i+3] = 1;
			}
		}
		
		dstCtx.putImageData(workImageData, canvasProp.dx, canvasProp.dy);
	}
	function calcCanvasPosition(sw, sh, dw, dh){
		var diffWidth = dw - sw, diffHeight = dh - sh;
		var rtn = {};
		
		if(diffWidth >= 0 && diffHeight >= 0){
			rtn = { dx: diffWidth / 2, dy: diffHeight / 2, width: sw, height: sh }
		}
		else if(diffWidth < 0 && diffHeight >= 0){
			rtn = { dx: 0, dy: (dh - dh * dw / sw) / 2, width: dw, height: sh * dw / sw }
		}
		else if(diffWidth >= 0 && diffHeight < 0){
			rtn = { dx: (dw - dw * dh / sh) / 2, dy: 0, width: dw * dh / sh, height: dh }
		}
		else {
			if(sw / sh >= dw / dh){ rtn = { dx: 0, dy: (dh - sh * dw / sw) / 2, width: dw, height: sh * dw / sw } }
			else { rtn = { dx: (dw - sw * dh / sh) / 2, dy: 0, width: sw * dh / sh, height: dh } }
		}
		return rtn;
	}
}, {
	preloadImages : [
		'./images/balloon.png',
		'./images/bird1.png', './images/bird2.png', './images/bird3.png', './images/bird4.png',
		'./images/cloud_fast.png', './images/cloud_slow.png',
		'./images/eat_mouse1.png', './images/eat_mouse2.png',
		'./images/error.png', './images/error_txt.png',
		'./images/fin_left1.png', './images/fin_left2.png', './images/fin_right1.png', './images/fin_right2.png',
		'./images/fin_music.png', './images/fin_remote.png',
		'./images/hammer.png', './images/island.png',
		'./images/mogu1.png', './images/mogu2.png',
		'./images/note1.png', './images/note2.png',
		'./images/tail1.png', './images/tail2.png',
		'./images/wave_01.png', './images/wave_02.png',
		'./images/whale.png', './images/whale_drop.png', './images/whale_error.png', './images/whale_music.png', './images/whale_sideways.png', './images/whale_stop.png',
		'./images/wordsBalloon.png', './images/wordsBalloon_.png'
	]
}, {
	preloadAudios : [
	]
});
